const controller = {
  created() {
    this.init();
  },
  computed: {
    // 新增表单过滤表格配置展示的数据
    filteredShowForm() {
      return this.config.tableConfig.tableColumnData.filter(
        (option) => option.form === true
      );
    },
    // 新增表单编辑过滤表格配置展示的数据
    filteredShowEdit() {
      return this.config.tableConfig.tableColumnData.filter(
        (option) => option.edit === true
      );
    },
  },
  methods: {
    // 初始化数据
    init() {
      try {
        if (!this.config) throw new Error("config.js文件未配置！");
        // 配置查询参数
        for (let item of this.config.paramConfig.queryParams) {
          if (!item.key || !item.key === "" || !item.label || item.label === "")
            throw new Error(
              "查询参数配置必填项存在未定义！" + JSON.stringify(item)
            );
          const newItem = {
            default: item.default || undefined,
            size: item.size || "small",
            necessary: item.necessary || false,
            ignoreReset: item.ignoreReset || false,
            type: item.type || "input",
          }
          
          this.$set(Object.assign(item, newItem))

          // 查询参数值绑定
          this.$set(
            this.config.paramConfig.queryParamsMaps,
            [item.key],
            item.default ? item.default : undefined
          );
        }
        // 检查表格配置
        this.config.tableConfig.tableColumnData.forEach((item) => {
          this.$set(item, "align", !item.align ? "center" : item.align);
          this.$set(item, "show", !item.show ? true : false);
          this.$set(item, "width", !item.width ? 150 : item.width);          
          this.$set(item, "type", !item.type ? "input" : item.type);
          item.type === 'select' ? this.$set(item, "multiple", !item.multiple ? false : true) : () => {};
          item.type === 'select' ? this.$set(item, "tableEdit", !item.tableEdit ? false : true) : () => {};
          item.type === 'select' ? this.$set(item, "size", !item.size ? 'mini' : item.size) : () => {};
          this.$set(item, "fixed", !item.fixed ? false : item.fixed);
          this.$set(item, "copy", !item.copy ? false : true);
          this.$set(item, "tooltip", !item.tooltip ? false : item.tooltip);
          this.$set(item, "sortable", !item.sortable ? false : true);
          this.$set(
            item,
            "valueFormat",
            !item.valueFormat ? "yyyy-MM-dd" : item.valueFormat
          );
          this.$set(item, "edit", !item.edit ? false : true);
          // 能否编辑
          this.$set(item, "editDisabled", !item.editDisabled ? false : true);
          this.$set(item, "form", !item.form ? false : true);
          this.$set(
            item,
            "rules",
            !item.form ? false : !item.rules ? false : true
          );
          this.config.tableConfig.showSummary ? this.$set(item, "notSummary", !item.notSummary ? true : false) : () => {};
          this.$set(
            item,
            "sortOrders", ["ascending", "descending"]
          );
        });
        // 替换硬编码 分页字段
        if (this.config.publicConfig.showPageCom) {
          if (
            !this.config.publicConfig.pageSize ||
            this.config.publicConfig.pageSize === "" ||
            !this.config.publicConfig.currentPage ||
            this.config.publicConfig.currentPage === ""
          ) {
            throw new Error("开启了分页，但是分页分页硬编码未配置！");
          }
          this.config.pageConfig = {
            [this.config.publicConfig.pageSize]: 20,
            [this.config.publicConfig.currentPage]: 1,
          };
        }
        // 请求数据
        if (this.config.publicConfig.defaultRequest) {
          this.config.tableConfig.tableLoading = false;
          this.getDataList();
        } else {
          this.config.tableConfig.tableLoading = false;
        }       
      } catch (err) {
        this.$message.error(err);
      }
    },
    // 弹窗确认
    async dialogConfirm() {
      this.$refs["form"].validate(async (valid) => {
        if (valid && this.config.dialogConfig.mode === "add") {
          const result = await new Promise((resolve, reject) => {
            this.config
              .addList(
                Object.assign(
                  {},
                  this.config.dialogConfig.form,
                  this.config.dialogConfig.auxiliaryForm
                )
              )
              .then((res) => {
                resolve(res);
              })
              .catch((err) => {
                reject(err);
              });
          });
          this.handleHttpRes(result);
        } else {
          const result = await new Promise((resolve, reject) => {
            this.config
              .editList(
                Object.assign(
                  {},
                  this.config.dialogConfig.form,
                  this.config.dialogConfig.auxiliaryForm
                )
              )
              .then((res) => {
                resolve(res);
              })
              .catch((err) => {
                reject(err);
              });
          });
          this.handleHttpRes(result);
        }
      });
    },
    // 重置
    reset() {
      Object.keys(this.config.paramConfig.queryParamsMaps).forEach(item => {
        if (!this.config.paramConfig.queryParams.find(obj => obj.ignoreReset && obj.key === item)) {
          this.config.paramConfig.queryParamsMaps[item] = undefined;
        }
      });
      if (!this.config.publicConfig.changeParamsRequest) return;
      this.getDataList();
    },
    // 网络请求
    async getDataList() {
      // 检查必填参数是否选择
      if (!this.checkNecessaryParams()) return;
      if (this.config.tableConfig.loading)
        this.config.tableConfig.tableLoading = true;
      const result = await new Promise((resolve, reject) => {
        this.config
          .getList(
            this.config.publicConfig.showPageCom
              ? Object.assign(
                  {},
                  this.dateDecomposition(
                    JSON.parse(
                      JSON.stringify(this.config.paramConfig.queryParamsMaps)
                    ),
                    JSON.parse(
                      JSON.stringify(this.config.paramConfig.queryParams)
                    )
                  ),
                  this.config.pageConfig,
                  this.config.auxiliaryParams
                )
              : this.dateDecomposition(
                  JSON.parse(
                    JSON.stringify(this.config.paramConfig.queryParamsMaps)
                  ),
                  JSON.parse(
                    JSON.stringify(this.config.paramConfig.queryParams)
                  )
                )
          )
          .then((res) => {
            resolve(res);
          })
          .catch((err) => {
            reject(err);
          });
      });
      this.handleHttpResult(result);
    },
    // 检查本地是否有表格配置 有则重新设置表格
    getLocaltionOptionsetTableData() {
      if (localStorage.getItem(this.config.publicConfig.name)) {
        this.config.tableOptionConfig.treeDataSave =
          this.config.tableConfig.tableColumnData.map((item, index) => ({
            label: item.label,
            id: index,
            prop: item.prop,
            show: item.show,
          }));
        this.setTableSrotAndShow(
          JSON.parse(localStorage.getItem(this.config.publicConfig.name))
        );
      } else {
        this.config.tableOptionConfig.treeDataSave =
          this.config.tableConfig.tableColumnData.map((item, index) => ({
            label: item.label,
            id: index,
            prop: item.prop,
            show: item.show,
          }));
      }
    },
    // 检查必填参数是否设置
    checkNecessaryParams() {
      try {
        let arr = this.config.paramConfig.queryParams.filter(
          (obj) => obj.necessary && obj.necessary === true
        );
        for (const item of arr) {
          if (!this.config.paramConfig.queryParamsMaps[item.key]) {
            throw new Error("必填查询参数未填！" + item.label);
          }
        }
        return true;
      } catch (err) {
        this.$message.error(err);
        return false;
      }
    },
    // 对日期范围查询的参数进行设置
    dateDecomposition(queryList, paramsOption) {
      try {
        for (const prop of Object.keys(queryList)) {
          if (Array.isArray(queryList[prop])) {
            let result = paramsOption.find((obj) => obj.key === prop);
            if (result && result.queryDateKey && result.queryDateKey !== "") {
              queryList[result.queryDateKey[0]] = queryList[prop][0];
              queryList[result.queryDateKey[1]] = queryList[prop][0];
              delete queryList[prop];
            } else {
              throw new Error(
                "没找到日期范围配置中对应的开始/结束key,未配置" +
                  JSON.stringify(result)
              );
            }
          }
        }
        return queryList;
      } catch (err) {
        this.$message.error(err);
      }
    },
    // 参数输入框输入 节流
    paramsInput() {
      // 是否开启自动查询参数
      if (!this.config.publicConfig.changeParamsRequest) return;
      if (this.config.inputQueryTimer) {
        clearTimeout(this.config.inputQueryTimer);
      }
      this.config.inputQueryTimer = setTimeout(() => {
        this.handleQuery();
        this.config.inputQueryTimer = null;
      }, this.config.publicConfig.inputDelay);
    },
    // 自动请求查询
    handleQuery() {
      // 是否开启自动查询参数
      if (!this.config.publicConfig.changeParamsRequest) return;
      this.getDataList();
    },
    // 点击查询
    clickQery() {
      this.getDataList();
    },
    // crud按钮点击
    buttonClickHandler(click) {
      this[click]();
    },
    // crud新增
    add() {
      // 配置form表单
      try {
        this.$set(this.config.dialogConfig, "form", {});
        this.config.tableConfig.tableColumnData.forEach((item) => {
          if (item.rules) {
            this.$set(
              this.config.dialogConfig.rules,
              [item.prop],
              [
                {
                  required: true,
                  message: item.prop + "不能为空",
                  trigger: "blur",
                },
              ]
            );
          }
          if (item.form) {
            if(item.type) {
              this.$set(this.config.dialogConfig.form, [item.prop], undefined);
            } else {
              throw new Error('开启表单配置后必需配置表单类型！')
            }
          }
        });
        this.config.dialogConfig.dialogVisible = true;
        this.config.dialogConfig.mode = "add";
        this.config.dialogConfig.title = "新增";
      } catch(err) {
        this.$message.error(err)
      }

    },
    // 导出
    async exp() {
      const result = await new Promise((resolve, reject) => {
        this.config
          .exportList()
          .then((res) => {
            resolve(res);
          })
          .catch((err) => {
            reject(err);
          });
      });
      this.handleHttpRes(result);
    },
    // 多选删除
    async del() {
      const result = await new Promise((resolve, reject) => {
        this.config
          .deleteMultipleList()
          .then((res) => {
            resolve(res);
          })
          .catch((err) => {
            reject(err);
          });
      });
      this.handleHttpRes(result);
    },
    // 过滤表格配置不展示的数据
    filteredShowOptions(option) {
      return option.filter((option) => option.show === true);
    },
    // 过滤表格配置中 select 类型数据
    filteredSelectOptions(option, value) {
      return option.filter((option) => option.value === value);
    },
    // 表格多选
    handleSelectionChange(selection) {
      this.config.tableConfig.ids = selection.map(
        (item) => item[this.config.tableConfig.idsKey]
      );
      this.config.tableConfig.ids.lenght > 0
        ? this.config.crudConfig.del.disabled === false
        : this.config.crudConfig.del.disabled === true;
    },
    // 表格排序
    handleSortChange(column, prop, order) {
      this.config.auxiliaryParams[this.config.publicConfig.orderByColumn] = column.prop;
      this.config.auxiliaryParams[this.config.publicConfig.orderByDesc.key] = this.config.publicConfig.orderByDesc.enable ? column.order : this.config.publicConfig.orderByDesc[column.order]
      this.getDataList();
    },
    // 复制文字
    copyText() {
      this.$message.success('复制成功！')
    },
    // 编辑
    handleEdit(index, row) {
      this.$set(this.config.dialogConfig, "form", {});
      this.config.tableConfig.tableColumnData.forEach((item) => {
        if (item.edit) {
          this.$set(this.config.dialogConfig.form, [item.prop], row[item.prop]);
        }
      });
      this.config.dialogConfig.mode = "edit";
      this.config.dialogConfig.title = "编辑";
      this.config.dialogConfig.dialogVisible = true;
    },
    // 表格内编辑 只针对 type:'select' 可在父组件重写
    async tableEditChange(row, prop) {
      const result = await new Promise((resolve, reject) => {
        this.config
          .editList(
            Object.assign(
            {},
            { id: row.id, [prop]:row[prop] },
            this.config.dialogConfig.auxiliaryForm
            )
          )
          .then((res) => {
            resolve(res);
          })
          .catch((err) => {
            reject(err);
          });
      });
      this.handleHttpRes(result);
    },
    // 删除数据
    async handleDel(row) {
      const result = await new Promise((resolve, reject) => {
        this.config
          .deleteList(row.id)
          .then((res) => {
            resolve(res);
          })
          .catch((err) => {
            reject(err);
          });
      });
      this.handleHttpRes(result);
    },
    // 列表数据请求处理
    handleHttpResult(res) {
      if(res.err) {
        this.$message.error(res.err)
      } else {
        this.config.tableConfig.tableData = res.data
        if(this.config.publicConfig.showPageCom) this.config.total = res.total  
        this.getLocaltionOptionsetTableData()
      }
      setTimeout(() => {
        this.config.tableConfig.tableLoading = false
      }, this.config.publicConfig.afterLoding);
    },
    // 请求后处理
    handleHttpRes(res) {
      if(res.err) {
        this.$message.error(res.err)
      } else {
        this.$message.success(res.msg)
      }
      setTimeout(() => {
        this.config.tableConfig.tableLoading = false
      }, this.config.publicConfig.afterLoding);
    },
    // 表单upload组件上传之前回调
    handleBeforeUpload() {
      // 校检文件大小
      if (this.fileSize) {
        const isLt = file.size / 1024 / 1024 < this.config.publicConfig.filesize;
        if (!isLt) {
          this.$message.error(`上传文件大小不能超过 ${this.config.publicConfig.filesize} MB!`);
          return false;
        }
      }
      return true;
    },
    // 表单upload组件上传成功回调
    handleUploadSuccess(item){
      return (response, file, fileList) => {
        const result = this.config.handleUploadSuccessCallBack(response)
        if(result.err) {
          this.$message.err(result.err)
        } else {
          if (result.msg) this.$message.success(result.msg)
          this.config.dialogConfig.form[item.prop] = result.data
        }
      }
    },
    // 表单upload组件上传失败
    handleUploadError() {
      return (response, file, fileList) => {
        const result = this.config.handleUploadErrorCallBack(response)
        if(result.err) {
          this.$message.err(result.err)
        }
      }
    },
    // 表单upload组件上传数量超出限制
    handleUploadExceed() {
      this.$message.warning(`文件多选已超出选择上限，重新选择！`);
    },
    // 自定义控制表格合计列是否展示
    customSummaryMethod({ columns, data }) {
      const sums = [];
      const arr = this.config.tableConfig.tableColumnData.filter(obj => obj.notSummary === true)
      columns.forEach((column, index) => {
        if (index === 0) {
          sums[index] = '合计';
          return;
        }
        const values = data.map(item => Number(item[column.property]));        
        // 检查当前列是否在不需要合计的列配置中
        if (arr.find(obj => obj.prop === column.property)) {
          // 计算总和
          const sum = values.reduce((prev, curr) => prev + curr, 0);
          // 判断结果是否为NaN、无穷大或无穷小
          if (!isFinite(sum) || isNaN(sum)) {
            sums[index] = '-';
          } else {
            sums[index] = sum;
          }
        } else {
          // 对于不进行数值合计的列，显示为“-”
          sums[index] = '-';
        }
      });
      return sums;
    },
    // 修改分页大小
    handleSizeChange(val) {
      this.config.pageConfig[this.config.publicConfig.pageSize] = val;
      this.config.pageConfig[this.config.publicConfig.currentPage] = 1;
      this.getDataList();
    },
    // 修改分页页签
    handleCurrentChange(val) {
      this.config.pageConfig[this.config.publicConfig.currentPage] = val;
      this.getDataList();
    },
    // 展示/隐藏表格配置组件
    switchDrawer() {
      this.config.tableOptionConfig.drawer =
        !this.config.tableOptionConfig.drawer;
      this.setDrawerData();
    },
    // 设置表格配置数据
    setDrawerData() {
      if (this.config.tableOptionConfig.drawer) {
        let option = [];
        // 检查本地是否有表格配置
        if (localStorage.getItem(this.config.publicConfig.name)) {
          option = JSON.parse(
            localStorage.getItem(this.config.publicConfig.name)
          ).map((item, index) => ({
            label: item.label,
            id: index,
            prop: item.prop,
            show: item.show,
          }));
        } else {
          option = this.config.tableConfig.tableColumnData.map(
            (item, index) => ({
              label: item.label,
              id: index,
              prop: item.prop,
              show: item.show,
            })
          );
        }
        this.config.tableOptionConfig.treeData = option;
      }
    },
    // 能否拖拽
    allowDrag(draggingNode) {
      return true;
    },
    // 开启拖拽
    allowDrop(draggingNode, dropNode, type) {
      if (type !== "inner") {
        return true;
      } else {
        return false;
      }
    },
    // 修改表格配置每项状态
    changeTreeState(prop) {
      const item = this.config.tableOptionConfig.treeData.find(
        (item) => item.prop === prop
      );
      if (item) item.show = !item.show;
    },
    // 清空表格配置
    clearLocationTableOption() {
      this.$confirm("此操作将永久删除该页面持久化表格配置, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          localStorage.removeItem(this.config.publicConfig.name);
          this.setTableSrotAndShow(this.config.tableOptionConfig.treeDataSave);
          this.config.tableOptionConfig.treeData = JSON.parse(
            JSON.stringify(this.config.tableOptionConfig.treeDataSave)
          );
          this.$message({
            type: "success",
            message: "删除配置成功!",
          });
        })
        .catch((err) => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },
    // 保存表格配置
    saveTableOption() {
      if (
        this.config.publicConfig.name &&
        this.config.publicConfig.name !== ""
      ) {
        localStorage.setItem(
          this.config.publicConfig.name,
          JSON.stringify(this.config.tableOptionConfig.treeData)
        );
        this.setTableSrotAndShow(this.config.tableOptionConfig.treeData);
        this.$message({
          type: "success",
          message: "保存配置成功!",
        });
      } else {
        this.$message({
          type: "error",
          message:
            "保存配置失败!未配置持久化表格name!" +
            this.config.publicConfig.name,
        });
      }
    },
    // 设置表格数据展示和排序
    setTableSrotAndShow(treeData) {
      let b = treeData;
      // 根据 b 对象数组中的 prop 属性值来排序 a 对象数组
      this.config.tableConfig.tableColumnData.sort(function (objA, objB) {
        // 在这里根据你的需求定义排序规则
        let indexA = b.findIndex(function (item) {
          return item.prop === objA.prop;
        });
        let indexB = b.findIndex(function (item) {
          return item.prop === objB.prop;
        });
        // 返回负数表示 propA 应该排在 propB 之前
        if (indexA < indexB) {
          return -1;
        }
        // 返回正数表示 propA 应该排在 propB 之后
        if (indexA > indexB) {
          return 1;
        }
        // 返回 0 表示 propA 和 propB 相等，排序不变
        return 0;
      });
      this.config.tableConfig.tableColumnData.forEach((item, index) => {
        item.show = b[index].show;
      });
    },
    handleClose(done) {
      this.$confirm("确认关闭？")
        .then((_) => {
          done();
        })
        .catch((_) => {});
    },
  },
};

export default controller;
